package com.example.testwebrtc

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

import org.webrtc.*

import org.webrtc.PeerConnectionFactory.InitializationOptions
import org.webrtc.MediaStream

import org.webrtc.SurfaceViewRenderer

import org.webrtc.PeerConnection

import org.webrtc.PeerConnectionFactory


import org.webrtc.VideoCapturer

import org.webrtc.SurfaceTextureHelper

import org.webrtc.DefaultVideoDecoderFactory

import org.webrtc.DefaultVideoEncoderFactory

import org.webrtc.EglBase
import org.webrtc.Camera1Enumerator


class MainActivity1 : AppCompatActivity() {
    var peerConnectionFactory: PeerConnectionFactory? = null
    var peerConnectionLocal: PeerConnection? = null
    var peerConnectionRemote: PeerConnection? = null
    var localView: SurfaceViewRenderer? = null
    var remoteView: SurfaceViewRenderer? = null
    var mediaStreamLocal: MediaStream? = null
    var mediaStreamRemote: MediaStream? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val eglBaseContext = EglBase.create().eglBaseContext

        // create PeerConnectionFactory

        // create PeerConnectionFactory
        PeerConnectionFactory.initialize(
            InitializationOptions
                .builder(this)
                .createInitializationOptions()
        )
        val options = PeerConnectionFactory.Options()
        val defaultVideoEncoderFactory = DefaultVideoEncoderFactory(eglBaseContext, true, true)
        val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext)
        peerConnectionFactory = PeerConnectionFactory.builder()
            .setOptions(options)
            .setVideoEncoderFactory(defaultVideoEncoderFactory)
            .setVideoDecoderFactory(defaultVideoDecoderFactory)
            .createPeerConnectionFactory()

        val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBaseContext)
        // create VideoCapturer
        // create VideoCapturer
        val videoCapturer: VideoCapturer? = createCameraCapturer(true)
        val videoSource = peerConnectionFactory!!.createVideoSource(videoCapturer!!.isScreencast)
        videoCapturer.initialize(surfaceTextureHelper, applicationContext, videoSource.capturerObserver)
        videoCapturer.startCapture(480, 640, 30)

        localView = findViewById(R.id.local_view)
        localView!!.setMirror(true)
        localView!!.init(eglBaseContext, null)

        // create VideoTrack

        // create VideoTrack
        val videoTrack = peerConnectionFactory!!.createVideoTrack("100", videoSource)
//        // display in localView
//        videoTrack.addSink(localView);
        val remoteSurfaceTextureHelper = SurfaceTextureHelper.create("RemoteCaptureThread", eglBaseContext)
        // create VideoCapturer
        // create VideoCapturer
        val remoteVideoCapturer: VideoCapturer? = createCameraCapturer(false)
        val remoteVideoSource = peerConnectionFactory!!.createVideoSource(remoteVideoCapturer!!.isScreencast)
        remoteVideoCapturer!!.initialize(remoteSurfaceTextureHelper, applicationContext, remoteVideoSource.capturerObserver)
        remoteVideoCapturer.startCapture(480, 640, 30)

        remoteView = findViewById(R.id.remote_view)
        remoteView!!.setMirror(true)
        remoteView!!.init(eglBaseContext, null)

        remoteView!!.setZOrderOnTop(true)
        // create VideoTrack
        Log.d("ansion","test222222222")
        // create VideoTrack
        val remoteVideoTrack = peerConnectionFactory!!.createVideoTrack("102", remoteVideoSource)
//        // display in remoteView
//        remoteVideoTrack.addSink(remoteView);


        //        // display in remoteView
//        remoteVideoTrack.addSink(remoteView);
        mediaStreamLocal = peerConnectionFactory!!.createLocalMediaStream("mediaStreamLocal")
        mediaStreamLocal!!.addTrack(videoTrack)

        mediaStreamRemote = peerConnectionFactory!!.createLocalMediaStream("mediaStreamRemote")
        mediaStreamRemote!!.addTrack(remoteVideoTrack)

        call(mediaStreamLocal!!, mediaStreamRemote!!)
    }

    private fun createCameraCapturer(isFront: Boolean): VideoCapturer? {
        val enumerator = Camera1Enumerator(false)
        val deviceNames = enumerator.deviceNames

        // First, try to find front facing camera
        for (deviceName in deviceNames) {
            if (if (isFront) enumerator.isFrontFacing(deviceName) else enumerator.isBackFacing(deviceName)) {
                val videoCapturer: VideoCapturer? = enumerator.createCapturer(deviceName, null)
                if (videoCapturer != null) {
                    return videoCapturer
                }
            }
        }
        return null
    }

    fun call(localMediaStream: MediaStream, remoteMediaStream: MediaStream) {
        val iceServers: List<PeerConnection.IceServer> = ArrayList();
        peerConnectionLocal = peerConnectionFactory!!.createPeerConnection(iceServers,object : PeerConnectionImpl("peerConnection Local"){
            override fun onIceCandidate(p0: IceCandidate?) {
                peerConnectionRemote?.addIceCandidate(p0)
            }

            override fun onAddStream(p0: MediaStream?) {
                val localVideoTrack = p0?.videoTracks?.get(0)
                runOnUiThread {
                    localVideoTrack?.addSink(localView)
                }
            }
        })

        peerConnectionRemote = peerConnectionFactory!!.createPeerConnection(iceServers, object : PeerConnectionImpl("peerConnection Remote"){
            override fun onIceCandidate(p0: IceCandidate?) {
                peerConnectionLocal?.addIceCandidate(p0)
            }

            override fun onAddStream(p0: MediaStream?) {
                val remoteVideoSink = p0?.videoTracks?.get(0)
                runOnUiThread {
                    remoteVideoSink?.addSink(remoteView)
                }
            }
        })

        peerConnectionLocal!!.addStream(localMediaStream)
        peerConnectionLocal!!.createOffer(object : SdpObserverImpl("local offer sdp") {
            override fun onCreateSuccess(p0: SessionDescription?) {
                super.onCreateSuccess(p0)
                peerConnectionLocal?.setLocalDescription(SdpObserverImpl("local set local"), p0)
                peerConnectionRemote?.addStream(remoteMediaStream)
                peerConnectionRemote?.setRemoteDescription(SdpObserverImpl("remote set remote"), p0)
                peerConnectionRemote?.createAnswer(object : SdpObserverImpl("remote answer sdp") {
                    override fun onCreateSuccess(p0: SessionDescription?) {
                        super.onCreateSuccess(p0)
                        peerConnectionRemote?.setLocalDescription(SdpObserverImpl("remote set local"), p0)
                        peerConnectionLocal?.setRemoteDescription(SdpObserverImpl("local set remote"), p0)
                    }
                }, MediaConstraints())
            }
        }, MediaConstraints());
    }


}